package com.c2b.algorithm.leetcode.base;

import java.util.ArrayList;
import java.util.List;

/**
 * 划分字母区间
 * <p>字符串 S 由小写字母组成。我们要把这个字符串划分为尽可能多的片段，同一字母最多出现在一个片段中。返回一个表示每个字符串片段的长度的列表。</p>
 *
 * @author c2b
 * @since 2022/5/24 9:04
 */
public class LC763partitionLabels {

    /*
    输入：S = "ababcbacadefegdehijhklij"
    输出：[9,7,8]
    解释：
        划分结果为 "ababcbaca", "defegde", "hijhklij"。
        每个字母最多出现在一个片段中。
        像 "ababcbacadefegde", "hijhklij" 的划分是错误的，因为划分的片段数较少。

     提示：
        S的长度在[1, 500]之间。
        S只包含小写字母 'a' 到 'z'
     */


    /**
     * 划分字母区间
     *
     * @param s 字符串
     * @return java.util.List<java.lang.Integer> 每个片段长度组成的集合
     * @author c2b
     * @since 2022/5/24 9:25
     */
    public List<Integer> partitionLabels(String s) {
        // 该数组记录每个元素最后出现的位置
        int[] lastSeenPosition = new int[26];
        char[] chars = s.toCharArray();
        for (int i = 0; i < chars.length; i++) {
            lastSeenPosition[chars[i] - 'a'] = i;
        }
        List<Integer> partition = new ArrayList<>();
        int start = 0;
        // 出现过的字母中最后所在的位置
        int end = 0;
        for (int i = 0; i < chars.length; i++) {
            end = Math.max(lastSeenPosition[chars[i] - 'a'], end);
            // 如果i来到了该段字母最后的位置。需要划分一次
            if (i == end) {
                partition.add(end - start + 1);
                start = end + 1;
            }
        }
        return partition;
    }
}
